/*
 * session.hpp
 *
 *  Created on: 2019-1-9
 *      Author: Dylan.Gao
 */

#ifndef _DM_SESSION_SESSION_HPP_
#define _DM_SESSION_SESSION_HPP_

#include <dm/session/common.hpp>
#include <dm/timestamp.hpp>

namespace dm{
namespace session{

class CRtsMonitor;
class CLogMonitor;
class CTimedMonitor;

class CSession{
public:
	enum{
#ifdef SESSION_RTS_MAX
		MaxRts = SESSION_RTS_MAX,
#else
		MaxRts = 40,
#endif

#ifdef SESSION_LOG_MAX
		MaxLog = SESSION_LOG_MAX,
#else
		MaxLog = 10,
#endif

#ifdef SESSION_TIMED_MAX
		MaxTimed = SESSION_TIMED_MAX,
#else
		MaxTimed = 40,
#endif
	};

public:
	CSession();

	bool init( const userid_t& userId,const dm::CTimeStamp& n,const dm::CTimeStamp::s_t& aliveSecs=300 );
	bool update( const mod_t& mod,const userid_t& userId,const dm::CTimeStamp& n,const dm::CTimeStamp::s_t& aliveSecs=300 );
	bool free( const mod_t& mod,const userid_t& userId );

	bool isIdle( const dm::CTimeStamp& n )const;
	bool isTimeout( const dm::CTimeStamp& n )const;

	inline const dm::CTimeStamp& deadline()const{
		return m_deadline;
	}

	inline void setDeadline( const dm::CTimeStamp& n ){
		m_deadline = n;
	}

	inline const mod_t& mod()const{
		return m_mod;
	}

	inline void setMod( const mod_t& m ){
		m_mod = m;
	}

	inline const userid_t& userId()const{
		return m_userId;
	}

	inline void setUserId( const userid_t& id ){
		m_userId = id;
	}

	int rtsCount()const;
	int logCount()const;
	int timedCount()const;

	CRtsMonitor* getFreeRts();
	CRtsMonitor* getRts( const mod_t& mod );

	CLogMonitor* getFreeLog();
	CLogMonitor* getLog( const mod_t& mod );

	CTimedMonitor* getFreeTimed();
	CTimedMonitor* getTimed( const mod_t& mod );

	void free();
private:
	lockshared_t m_lock;

	dm::CTimeStamp m_deadline;
	mod_t m_mod;
	userid_t m_userId;

	mod_t m_rts[MaxRts];       // realtime data monitors
	mod_t m_logs[MaxLog];      // log monitors
	mod_t m_timeds[MaxTimed];  // timestamped data monitors
};

}
}

#endif /* INCLUDE_DM_SESSION_SESSION_HPP_ */
